Skip to content

feat(daemon): expose control-plane action registry over HTTP + WS#143

Merged
vreshch merged 1 commit intomasterfrom
feature/control-plane-daemon
Apr 19, 2026
Merged

feat(daemon): expose control-plane action registry over HTTP + WS#143
vreshch merged 1 commit intomasterfrom
feature/control-plane-daemon

Conversation

@vreshch
Copy link
Copy Markdown
Contributor

@vreshch vreshch commented Apr 19, 2026

Summary

Wires @agentage/core@0.10.0's action registry into the daemon so host UIs (desktop, web dashboard, future MCP clients) can dispatch control-plane actions: update the CLI, clone a project from a remote, install an agent.

The registry lives in core (merged in agentkit#105); this PR plugs it into the daemon's existing Express + WebSocket server and ships three reference actions. Adjacent CLAUDE.md note: each host owns its actions so they can bind to the host's real state (shell adapter, VERSION, projects list). A follow-up will re-export the core-side reference factories from the top-level barrel for hosts that want the pre-built versions.

Design

  • Registry singleton (src/daemon/actions.ts) — built once on first access, registers the three built-in actions.
  • HTTP surface:
    • GET /api/actions{ success, data: ActionManifest[] } for introspection
    • POST /api/actions/:name → SSE stream of InvokeEvent (acceptedprogress*result | error). Headers: x-capabilities (comma-separated; defaults to * for local callers), x-caller-id. Body: { input, version?, idempotencyKey? }. Client disconnect aborts the invocation via res.on('close') — used res rather than req to avoid premature aborts when the JSON body finishes streaming.
  • WebSocket surface:
    • { type: 'invoke', requestId, action, input, version?, idempotencyKey?, capabilities? } — streams { type: 'action_event', requestId, event: InvokeEvent } back, tagged with requestId for multiplexing concurrent invocations
    • { type: 'cancel_invoke', requestId } — aborts an in-flight invocation
  • Three actions (src/daemon/actions/*.ts): cli:update (semver/latest validated, shells npm install -g), project:addFromOrigin (git URL validated, derives name, optional branch), agent:install (npm install in a workspace dir). Each declares a distinct capability (cli.write, project.write, agent.write) and scope: 'machine'.

Changes

  • src/daemon/actions.ts — registry bootstrap singleton
  • src/daemon/actions/ — cli-update, project-add-from-origin, agent-install + shared ShellExec/ActionProgress types
  • src/daemon/routes.ts — adds wireActionRoutes, SSE streaming helper, capability header parsing
  • src/daemon/websocket.tsinvoke / cancel_invoke message handling, active invocations map
  • Tests: actions.test.ts, actions/actions.test.ts, routes.actions.test.ts (13 new tests)
  • package.json — bumps @agentage/core to ^0.10.0

Test plan

  • npm run verify — type-check + lint + format + build all green; 524/525 tests pass (one unrelated pre-existing worker-timeout flake in ensure-daemon.test.ts — reproducible on master, not touched by this PR)
  • Route-level SSE parsing verified end-to-end (accepted, progress, result, error envelopes)
  • Capability auth verified (UNAUTHORIZED when header omits the required cap; * default works for local)
  • Follow-up: dogfood cli:update end-to-end from Desktop/Claude Code once an MCP or IPC client is wired
  • Follow-up: re-export reference factories from @agentage/core top-level so hosts don't need to copy them

Related

  • agentkit#105 (merged) — ships the @agentage/core/control module
  • agentkit#106 (merged) — publishes @agentage/core@0.10.0

Wires @agentage/core@0.10.0's action registry into the daemon so host
UIs (desktop, web, future MCP clients) can dispatch control-plane
actions: update the CLI, clone a project from a remote, install an agent.

- src/daemon/actions.ts — registry singleton, registers the three
  built-in actions bound to the real shell adapter + VERSION
- src/daemon/actions/{cli-update,project-add-from-origin,agent-install}.ts
  — domain-owned action factories with input validation
- GET /api/actions — list manifests (introspection for host UIs)
- POST /api/actions/:name — SSE stream of InvokeEvent (accepted →
  progress* → result|error), x-capabilities header for auth scoping,
  cancels invocation on client disconnect
- WS { type: 'invoke', requestId, action, input, ... } — streams
  action_event messages tagged with requestId; { type: 'cancel_invoke' }
  aborts an in-flight invocation

Bumps @agentage/core to ^0.10.0. Coverage: 13 new tests across action
factories, registry bootstrap, and route SSE streaming.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 19, 2026

🎉 PR Validation ✅ PASSED

Commit: a9721fcab1ea03104e47091c62d9a33f71c2e927
Branch: feature/control-plane-daemon

Checks:

  • ✅ Release guard (no version/changelog changes)
  • ✅ Dependencies installed
  • ✅ Type check passed
  • ✅ Linting passed
  • ✅ Format check passed
  • ✅ Tests + coverage passed
  • ✅ Build successful

Ready to merge!


🔗 View workflow run
⏰ Generated at: 2026-04-19T23:01:15.341Z

@vreshch vreshch merged commit 20e13c4 into master Apr 19, 2026
1 check passed
@vreshch vreshch deleted the feature/control-plane-daemon branch April 19, 2026 23:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant